package com.ray.service;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.RandomAccessFile;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import java.util.stream.Collectors;

import org.apache.ibatis.reflection.wrapper.BaseWrapper;
import org.apache.xmlbeans.impl.xb.xsdschema.NarrowMaxMin;
import org.apache.xmlbeans.impl.xb.xsdschema.impl.PublicImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.appengine.api.memcache.MemcacheServicePb.MemcacheSetResponse.SetStatusCode;
import com.google.appengine.api.search.query.QueryParser.restriction_return;
import com.google.appengine.repackaged.com.google.api.client.util.StreamingContent;
import com.mysql.jdbc.interceptors.ServerStatusDiffInterceptor;
import com.ray.bean.EnergyBean;
import com.ray.mapper.EnergyMapper;
import com.ray.util.ReturnStringUtil;
import com.ray.util.redis.RedisCache;
import com.ray.util.redis.RedisKey;
import com.sun.mail.mbox.Mailbox;
import com.tqdq.sdk.api.CommonUtil;
import com.tqdq.sdk.api.TQApi;
import com.tqdq.sdk.api.TQResponse;
import com.tqdq.sdk.helper.GeneralOperate;
import com.tqdq.sdk.helper.TriphaseMultipricePrepaidStepMeter;

/**
 * 电表service
 * @author nate
 *
 */
@Service
public class MaterService {
	@Autowired
	EnergyService energyService;
	@Autowired
	EnergyMapper energyMapper;
	
	
	 public static final String MATER_AUTH_CODE="e2d06fa4d82e08899ed5592393f55c75";//授权码
     public static final String MATER_SIGN="";//签名
     public static final String MATER_NONCE="bJ9tsdcEHBrQFX0a8LvPde";//随机码
//     public static final String MATER_NOTIFYIRL="http://ykqh7q.natappfree.cc/weixin/energy/materResponseUrl";//请求地址
     public static final String MATER_NOTIFYIRL="https://www.shinehao.net/weixin/energy/materResponseUrl";   //请求地址
//     public static final String MATER_NOTIFYIRL="http://vr5b3c.natappfree.cc/weixin/test/testMater";//请求地址
	 public static final TQApi TQ_API = new TQApi(MATER_AUTH_CODE,MATER_SIGN,MATER_NOTIFYIRL);
     public static final GeneralOperate GENERAL_OPERATE = new GeneralOperate(TQ_API);
     public static final String MATER_REDIS_KEY="mater_redis_key";
     public static final String ALERADY_USED_ORP_ID="alerady_used_orp_id";
     
//        try {
//        	method2("C:\\2.txt", jsonStr);
//        }catch(Exception e) {
//        	
//        }finally {
//        	return "SUCCESS";
//        }
     
     /**
      * 设置电表度数
      */
     public String  setElementValues(String jsonStr) {
    	String  returnStr="SUCCESS";
        System.out.println(jsonStr);
    	JSONArray jsonArray = JSONArray.parseArray(jsonStr);
    	if(jsonArray.size()>0) {
    		List<Map<String, Object>> listMap=(List<Map<String, Object>>) RedisCache.getDataFromRedis(MATER_REDIS_KEY);
    		Set<String> aleradyUsedOrpId=(Set<String>) RedisCache.getDataFromRedis(ALERADY_USED_ORP_ID);
    		if(aleradyUsedOrpId==null) {aleradyUsedOrpId=new HashSet<String>();}
    		if(listMap.size()<=0) {return "";}
    		List<EnergyBean> energyList=new ArrayList<EnergyBean>();
    		for(int i=0;i<jsonArray.size();i++) {
    			JSONObject jsonObject = jsonArray.getJSONObject(i);
    			try {
    				//结果是成功的
    				if("SUCCESS".equals(jsonObject.getString("status"))) {
    					String opr_id = jsonObject.getString("opr_id");
    					for(Map map:listMap) {
    						//相同并且没有使用过
    						if(opr_id.equals(map.get("opr_id")) && !aleradyUsedOrpId.contains(opr_id)) {
    							String value=jsonObject.getJSONArray("data").getJSONObject(0).getJSONArray("value").get(0).toString();
    							String engerNo=map.get("cid").toString();
    							EnergyBean energyBean =new EnergyBean();
    							energyBean.setNo(engerNo);
    							energyBean.setNumber(Double.parseDouble(value));
    							if(0 != energyBean.getNumber()) {
    								energyList.add(energyBean);
    							}
    							aleradyUsedOrpId.add(opr_id);
    							break;
    						}
    					}
    				}
    			}catch(Exception e) {//异常跳过本次循环,告诉那边整个结果重发
    				returnStr="ERROR";
    				continue;
    			}
    		}
    		if(energyList.size()>0) {
    			energyMapper.updateEnergyNumber(energyList);
    		}
    		/**
    		 * 获取已使用的orp_id
    		 */
    	    RedisCache.setDataToRedis(ALERADY_USED_ORP_ID, aleradyUsedOrpId, null);
    	}
 		return returnStr;
     }
     
     /**
      * 注册电表
      * @throws Exception 
      */
     public String  registerMater(String materNo) throws Exception {
    	TQResponse xx=	GENERAL_OPERATE.addController(materNo);
    	System.out.println(xx.toString());
    	if(!xx.getStatus().equals("SUCCESS")) {
    		throw new Exception("注册采集器失败");
    	}
    	List<Map<String,Object>> mapList=xx.getResponseContent();
    	Map<String,Object> map = mapList.get(0);
    	if(!"SUCCESS".equals(map.get("status"))) {
    		throw new Exception("注册采集器失败");
    	}
		TQResponse tt=	GENERAL_OPERATE.addElecMeter(materNo, materNo);
		if(!tt.getStatus().equals("SUCCESS")) {
    		throw new Exception("注册电表失败");
    	}
		Assert.isTrue(tt.getStatus().equals("SUCCESS"),"注册电表失败");
		System.out.println(tt.toString());
		mapList=tt.getResponseContent();
    	map = mapList.get(0);
    	if(!"SUCCESS".equals(map.get("status"))) {
    		throw new Exception("注册电表失败");
    	}
		return ReturnStringUtil.ADD_SUCCESS;
     }
     
     
     public String restMater(String no) {
    	 TriphaseMultipricePrepaidStepMeter meter = new TriphaseMultipricePrepaidStepMeter("191005268220", "191005268220", TQ_API);
		try {
			TQResponse tqResponse = meter.reset(no);
			System.out.println(tqResponse.toString());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	 
    	return "";
     }
     
     /**
      * 定时注册未注册成功的电表
      * @return
      */
     public String  timeingRegisterMater () {
    	 Map paramMap=new HashMap<>();
    	 paramMap.put("type", 1);//获取新型仪表
    	 paramMap.put("isRegister", "0");//获取新型仪表未注册成功的
    	 List<EnergyBean> notRegisterList = energyService.getAllEnergyNoPage(paramMap);
    	 if(notRegisterList.size()>0) {
    		for(EnergyBean energyBean:notRegisterList) {
    			try {
					this.registerMater(energyBean.getNo());
					energyBean.setIsRegister(1);
				} catch (Exception e) {
					energyBean.setIsRegister(0);
				}
    		}
    	 }
    	 List<EnergyBean> list=notRegisterList.stream().filter(dd->dd.getIsRegister().equals(1)).collect(Collectors.toList());
    	 if(list.size()>=0) {
    		 energyMapper.setEngerIsRegister(list);
    	 }
    	 return "SUCCESS";
     }
     
//    	 EnergyBean energyBeana = new EnergyBean();
//    	 energyBeana.setNo("191005268220");
//    	 alllEnergy.add(energyBeana);
//    	 EnergyBean energyBeana2 = new EnergyBean();
//    	 energyBeana2.setNo("190410045857");
//    	 alllEnergy.add(energyBeana2);
     /**
      * 定时读取所有电表度数
      */
     public  String timeingSendRequest() {
    	 Map paramMap=new HashMap<>();
    	 paramMap.put("type", 1);//只获取新型仪表
    	 paramMap.put("isRegister", "1");//获取新型仪表注册成功的
    	 paramMap.put("isAgree", "1");//获取允许使用的
    	 List<EnergyBean> alllEnergy=energyService.getAllEnergyNoPage(paramMap);
    	 if(alllEnergy.size()<=0) {
    		 return "";
    	 }
    	 List<Map<String, Object>> mapList=new ArrayList<Map<String, Object>>();
    	 Map<String,Object> map=new HashMap<String, Object>();
    	 map.put("time_out", 5);//请求有效时间
         map.put("must_online", true);
         map.put("retry_times", 1);//异常时重复请求次数
         map.put("type", 48);//类型是获取电表度数
    	 for(EnergyBean energyBean : alllEnergy) {
    		 Map<String,Object> oneMap = new HashMap<String,Object>(map);
    		 oneMap.put("opr_id", CommonUtil.generateOperateId());
    		 oneMap.put("address",energyBean.getNo());
    		 oneMap.put("cid", energyBean.getNo());
    		 mapList.add(oneMap);
    	 }
    	 RedisCache.setDataToRedis(MATER_REDIS_KEY, mapList, null);
    	 RedisCache.delKey(ALERADY_USED_ORP_ID);//清除已使用的key
    	 try {
			TQResponse tqResponse = TQ_API.readElecMeter(mapList);
			System.out.println(tqResponse.toString());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
       return "SUCCESS";
     }
     
     
	 /** 
	  * 第一种
	  * 
     * 追加文件：使用FileOutputStream，在构造FileOutputStream时，把第二个参数设为true 
     * 
     * @param fileName 
     * @param content 
     */  
   public static void method1(String file, String conent) {   
       BufferedWriter out = null;   
       try {   
            out = new BufferedWriter(new OutputStreamWriter(   
                   new FileOutputStream(file, false)));   
            out.write(conent);   
        } catch (Exception e) {   
            e.printStackTrace();   
        } finally {   
           try {   
                out.close();   
            } catch (IOException e) {   
                e.printStackTrace();   
            }   
        }   
    }   
  
   /** 
    * 
    * 第二种
     * 追加文件：使用FileWriter 
     * 
     * @param fileName 
     * @param content 
     */  
   public static void method2(String fileName, String content) {   
       try {   
           // 打开一个写文件器，构造函数中的第二个参数true表示以追加形式写文件   
            FileWriter writer = new FileWriter(fileName, true);   
            writer.write(content);   
            writer.close();   
        } catch (IOException e) {   
            e.printStackTrace();   
        }   
    }   
  
   /** 
     * 追加文件：使用RandomAccessFile 
     * 
     * @param fileName 
     *             文件名 
     * @param content 
     *             追加的内容 
     */  
   public static void method3(String fileName, String content) {   
       try {   
           // 打开一个随机访问文件流，按读写方式   
            RandomAccessFile randomFile = new RandomAccessFile(fileName, "rw");   
           // 文件长度，字节数   
           long fileLength = randomFile.length();   
           // 将写文件指针移到文件尾。   
            randomFile.seek(fileLength);   
            randomFile.writeBytes(content);   
            randomFile.close();   
        } catch (IOException e) {   
            e.printStackTrace();   
        }   
    }
	
	
	
	
}
